        TITL DAI FIRMWARE C437-C613  V1.0  Rev.1
        ORG   :C437
*
*
*
************************
* FPT NUMBER CONSTANTS *
************************
*
* For the first 7 numbers, the 1st byte is the
* power of 10 for division.
*
LC234   DATA  :00
        DATA  :02       FPT (2^1)/10^0
        DATA  :80
        DATA  :00
        DATA  :00
*
        DATA  :00
        DATA  :03       FPT (2^2)/10^0
        DATA  :80
        DATA  :00
        DATA  :00
*
        DATA  :01
        DATA  :01       FPT (2^4)/10^1
        DATA  :CC
        DATA  :CC
        DATA  :CD
*
        DATA  :02
        DATA  :02       FPT (2^8)/10^2
        DATA  :A3
        DATA  :D7
        DATA  :0A
*
        DATA  :04
        DATA  :03       FPT (2^16)/10^4
        DATA  :D1
        DATA  :B7
        DATA  :17
*
        DATA  :09
        DATA  :03       FPT (2^32)/10^9
        DATA  :89
        DATA  :70
        DATA  :5F
*
        DATA  :13
        DATA  :01       FPT (2^64)/10^19
        DATA  :EC
        DATA  :1E
        DATA  :4A
*
LC238   DATA  :7D       FPT (0.1)
        DATA  :CC
        DATA  :CC
        DATA  :CD
*
FP0     DATA  :00       FPT (0)
        DATA  :00
        DATA  :00
        DATA  :00
*
FP1     DATA  :01       FPT (1)
        DATA  :80
        DATA  :00
        DATA  :00
*
FP2     DATA  :02       FPT (2)
        DATA  :80
        DATA  :00
        DATA  :00
*
FP3     DATA  :02       FPT (3)
        DATA  :C0
        DATA  :00
        DATA  :00
*
FP4     DATA  :03       FPT (4)
        DATA  :80
        DATA  :00
        DATA  :00
*
FP5     DATA  :03       FPT (5)
        DATA  :A0
        DATA  :00
        DATA  :00
*
FP6     DATA  :03       FPT (6)
        DATA  :C0
        DATA  :00
        DATA  :00
*
FP7     DATA  :03       FPT (7)
        DATA  :E0
        DATA  :00
        DATA  :00
*
FP8     DATA  :04       FPT (8)
        DATA  :80
        DATA  :00
        DATA  :00
*
FP9     DATA  :04       FPT (9)
        DATA  :90
        DATA  :00
        DATA  :00
*
*********************************
* PRETTIES UP FPT OR INT NUMBER *
*********************************
*
* Entry: B:     Fix/float flag: (0=fix, 1=float).
*        A:     Nr. of useable digits in string in
*               00E4-F0 (not counting additional
*               digit for rounding).
*        00F1:  Nr. of digits before '.' (exponent).
*        00E4:  Sign '+' or '-'.
*        00E5:  Decimal point.
*        E6-F0: Digits.
* Exit:  All registers preserved.
*        00E3:  Length of string.
*        E4-F0: Output string.
*
* Format: Sign in 00E4 is blank or '-'.
*         If exponent is 0:
*               real case: '0.digits'
*               int. case: no final '.'
*               real case if INT: '.0'
*         If exponent < -1:  E-format
*         If exponent too large: E-format
*         In E-format no '.0'
*
PRTY    PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        LXI   H,:00E6   Startaddr digits
        MOV   C,A       Save nr. useable digits
        PUSH  B
        MVI   B,:00
        DAD   B         HL pnt to last useable digit
        MOV   A,M       Get last digit
        CPI   :35       Check for rounding
        JC    :C4AF     If <5
LC91    DCX   H
        MOV   A,M       Get digit before
        CPI   :39
        JZ    :C4A3     If it is 9
        INR   M         Rounding upwards
        JMP   :C4AF     Abort rounding
LC92    MVI   M,:30     Make digit before 0
        DCR   C         Decr. nr of digits
        JNZ   :C498     Cont. check for rounding
        MVI   M,:31     Make nr=1 if all digits 9
        LXI   H,:00F1
        INR   M         Incr nr of digits before '.'
LC93    POP   B
        INR   C         Incr. nr useable digits
        LDA   :00F1     Get nr of digits before '.'
        ORA   A
        JZ    :C4D8     If 0
        JM    :C4E1     If too many digits
        ADD   B         Add fix/float flag
        CMP   C
        JNC   :C4E1     If too many digits
        CALL  :C69C     Restore A, insert '.'
 REM after number string
LC94    MOV   A,C       Length string in A
        CALL  :C54B     Calc nr of digits for output
LC95    INR   A         Add 1
        LXI   H,:00E3
        MOV   M,A       String length in outbuf
        INX   H
        MOV   A,M       Get sign
        CPI   :2B       '+' ?
        JNZ   :C4D5     Then abort
        MVI   M,:20     Replace '+' by blank
LC96    JMP   :C14D     Popall, ret
 REM
* If format '0.digits':
 REM
LC97    CALL  :C51A     Move string right 1 pos.
        MVI   M,:30     Insert 0 in 00E5
        INR   C         Update nr of digits
        JMP   :C4C3     Update string
 REM
* If too many digits:
 REM
LC98    MVI   A,:01
        CALL  :C531     Move string left 1 pos,
 REM insert '.' after string
        MOV   A,C       Get nr of digits
        MVI   B,:00
        CALL  :C54B     Calc nr of digits for output
        MOV   B,A       in B
        LDA   :00F1     Get nr of digits before '.'
        DCR   A         Minus 1
        MVI   M,:45     'E' in buf after last digit
        INX   H
        INR   B         Incr. nr of digits
        ORA   A         Flags on exponent
        JP    :C4FF     If exp. positive
 REM
* If exponent negative:
 REM
        MVI   M,:2D     Store '-' in buffer
        INX   H
        INR   B         Incr nr of digits
        CMA
        INR   A         2-compl of exponent
 REM
* Exponent to buffer:
 REM
LC99    LXI   D,:2F0A
LC100   SUB   E         Exp.-10 (unit value)
        INR   D         ASCII-count 10's-value
        JNC   :C502     If rest exp. still >10
        ADI   :3A       Convert rest to Ascii
        MOV   E,A       in E
        MOV   A,D       Get 10's value
        CPI   :30
        JZ    :C513     If exp. <10
        MOV   M,A       10's value exp. in buf
        INX   H
        INR   B         Incr nr of digits
LC101   MOV   M,E       Unit value exp. in buf
        INX   H
        INR   B         Incr nr of digits
        MOV   A,B       into A
        JMP   :C4C7     Prepare string for output
*
* MOVE STRING IN OUTPUTBUFFER RIGHT 1 POS.:
*
* The contents of 00E5-EF is moved up one
* position to 00E6-F0.
*
* Entry: No conditions.
* Exit:  ABCDEF preserved.
*        HL points to 00E5.
*
LC102   PUSH  PSW
        PUSH  B
        PUSH  D
        LXI   H,:00F0   Highest destination address.
        MOV   D,H
        MOV   E,L
        DCX   D         Highest source address.
        MVI   B,:0B     Number of bytes.
LC103   LDAX  D         Get byte
        MOV   M,A       and move it.
        DCX   D
        DCX   H
        DCR   B
        JNZ   :C525     Next byte if not ready
        POP   D
        POP   B
        POP   PSW
        RET
*
* MOVE STRING IN OUTPUTBUFFER LEFT 1 POS.:
*
* The string, beginning on 00E6, is moved one
* memory location downwards. A '.' is inserted
* after the string.
*
* Entry: A: number of bytes to be transferred.
* Exit:  All registers preserved.
*
LC104   PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        MOV   B,A       Store number of bytes
        LXI   H,:00E5   Lowest destination address
        LXI   D,:00E6   Lowest source address
LC105   LDAX  D         Get byte
        MOV   M,A       and move it
        INX   D
        INX   H
        DCR   B
        JNZ   :C53C     Next byte if not ready
        MVI   M,:2E     Insert '.' after string
        POP   H
        POP   D
        POP   B
        POP   PSW
        RET
*
* CALCULATE NUMBER OF DIGITS FOR OUTPUT:
*
* Entry: Total nr of string digits in A and C.
*        B: Flag for INT (0) or FPT (1).
*        Digits in 00E4 to 00E4 + A.
* Exit:  A:  Nr of bytes for output:
*                  INT: excl. trailing '.0'
*                  FPT: incl. trailing '.0'
*        HL: If last non-zero byte is not '.':
*            points after last byte.
*            Else: INT: points to '.'
*                  FPT: after '.0'
*
LC106   PUSH  B
        PUSH  D
        LXI   H,:00E4   Startaddr string
        MOV   E,A       Total nr of digits in E
        MVI   D,:00
        DAD   D         Calc end of string
LC107   MOV   A,M       Get digit
        CPI   :30
        JNZ   :C55F     If non-zero
        DCX   H         Points to previous digit
        DCR   C         Decr nr of digits
        JMP   :C554     Again till non-zero found
 REM
* If non-zero digit found:
 REM
LC108   CPI   :2E       '.' ?
        INX   H
        JNZ   :C56F     Abort if not
        DCX   H         Pnts after last non-zero,
 REM non-'.' digit
        DCR   C         Excl. '.'
        DCR   B
        JNZ   :C56F     If INT case
        INX   H         ) If FPT case: pnts
        INX   H         ) after '.0'
        INR   C
        INR   C         Incl. '.0'
LC109   MOV   A,C       Nr of digits for output
        POP   D
        POP   B
        RET
*
********************************
* INPUT INTEGER NUMBER TO MACC *
********************************
*
* Read string of digits from line and convert
* it to binary in MACC.
*
* Entry: BC points to input character.
* Exit:  BC points after INT number.
*        ADEHL preserved.
*        CY=1: there were digits.
*        CY=0: No digits.
*
ICB     STC
        PUSH  PSW
        PUSH  D
        PUSH  H
        CALL  :C598     Clear MACC and 00E3-E6.
LC110   CALL  :C073     Get digit from line
        SUI   :30       Convert ASCII to binary
        JC    :C590     )
        CPI   :0A       ) Abort if no number
        JNC   :C590     )
        LXI   H,:C610   Addr INT(10)
        CALL  :C5A5     MACC=MACC*10 + digit
        JMP   :C57A     Next digit
LC111   DCR   D
        INR   D
        JNZ   :C2A2     If digits: Pop, ret
        JMP   :C2A9     If no digits: CY=0, Pop, ret
*
* CLEAR MACC AND 00E3-00E6:
*
* Both MACC and registers 00E3-E6 are loaded
* with the value of FPT (0).
*
* Exit: ABCE preserved. D=0.
*
LC112   LXI   H,:C45E   Addr. FPT(0)
        RST   4         Copy FPT(0) to MACC
        DATA  :0C
        LXI   H,:00E3
        RST   4         Copy FPT(0) to 00E3-E6
        DATA  :0F
        MVI   D,:00     Clear D
        RET
*
* MACC = MACC*10 + DIGIT FROM LINE:
*
* Entry: HL: points to INT (10).
*        A:  digit to be added.
*
LC113   RST   4         MACC=MACC*10 (INT)
        DATA  :54
LC114   INR   C
        DCR   D
        STA   :00E6     Digit in lobyte E3-E6
        LXI   H,:00E3
        RST   4         Add (E3-E6) to MACC (INT)
        DATA  :4E
        RET
*
*************************************
* CONVERT INTEGER NUMBER FOR OUTPUT *
*************************************
*
* Places ASCII string from INT MACC contents in
* output buffer 00E4-F0.
* 00E4 is sign, 00E5 is '.', 00E6-F0 is value,
* 00F1 is nr of digits.
*
* Exit: A: Number of digits.
*       BCDEHL preserved.
*
IBC     PUSH  B
        PUSH  D
        PUSH  H
        CALL  :C21E     Save MACC to TOS
        CALL  :C5E0     Abs.value of MACC in reg
 REM A,B,C,D; Prepare 00E4-E6
LC115   CALL  :C21E     Save MACC to TOS
        LXI   H,:C610   Addr INT(10)
        RST   4         MACC = remainder MACC/10
        DATA  :5A
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        MOV   A,D       Lobyte in A
        CALL  :C5FA     Digit into 00E5-F0
        CALL  :C234     Retrieve MACC from TOS
        RST   4         MACC = MACC/10 (INT)
        DATA  :57
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        ORA   B
        ORA   C
        ORA   D
        JNZ   :C5BB     Again if <>0
        CALL  :C606     '.' in 00E5; length in 00F1
        CALL  :C234     Retrieve MACC from TOS
        POP   H
        POP   D
        POP   B
        RET
*
* PREPARE 00E4-E6:
*
* 00E4-E6 is set to +00 or -00, depending on sign
* of contents MACC. In the MACC remains the absolute
* value. The registers A,B,C,D contain the original
* contents of the MACC.
*
* Exit: E=0. HL preserved. AFBCD corrupted.
*
LC116   PUSH  H
        LXI   H,:00E4
        RST   4         Copy MACC to reg A,B,C,D
        DATA  :15
        ORA   A         Set flags on sign
        MVI   M,:2B     '+' in 00E4
        JP    :C5F0     Jump if nr is positive
        MVI   M,:2D     Else '-' in 00E4
        RST   4         and make contents MACC pos.
        DATA  :60
LC117   INX   H
        MVI   M,:30     0 in 00E5
        INX   H
        MVI   M,:30     0 in 00E6
        MVI   E,:00     Digit count is 0
        POP   H
        RET
*
* STORE DIGIT IN OUTPUT BUFFER 00E5-00F0:
*
* Entry: Digit in A.
* Exit:  Digit in 00E5-F0 as most sign. digit.
*        E:  Count of digit in buffer.
*        BCDHL preserved. AF corrupted.
*
LC118   PUSH  H
        PUSH  PSW
        CALL  :C51A     Move contents buffer right
        POP   PSW
        ADI   :30       Make digit ASCII
        MOV   M,A       Digit in 00E5 inserted.
        INR   E         Update digit count.
        POP   H
        RET
*
* ADD A '.' TO A DIGIT STRING IN OUTPUTBUFFER:
*
* A '.' is placed at the beginning of a digit
* string in the output buffer. The length of the
* string is stored in 00F1.
*
* Entry: E:  Digit count.
*        HL: Points to 00E5.
* Exit:  A:  Count.
*        BCDEHL preserved.
*
LC119   CALL  :C51A     Move contents outbuf right
 REM one position
        MVI   M,:2E     '.' at begin of string
        MOV   A,E       Get digit count
        STA   :00F1     Store it in buffer
        RET
*
* DATA:
*
I10     DATA  :00       INT (10)
        DATA  :00
        DATA  :00
        DATA  :0A
*
*
*
        END
